package frame.exec
{
	import common.StructTime;
	import config.COLORCONFIG;
	import data.DataMonitor;
	import debug.ASSERT;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.text.TextFormatAlign;
	import flash.utils.Dictionary;
	import frame.IFrame;
	import nsdecl.ns_bindattr_filter;
	import nsdecl.ns_group_handler;
	import nsdecl.ns_group_hook;
	import nsdecl.ns_interactive_slot;
	import nsdecl.ns_vname_decl;
	import mx.utils.StringUtil;
	import proxy.DataAccess;
	import ui.basePannel;
	import ui.ui_button;
	import ui.ui_scroll_bar;
	import ui.ui_text;
	import ui.ui_text_block;
	import ui.uiGroup;
	import ui.uiUnit;
	import ui.uiWin;
	import ui.utils.attrControl;
	import ui.utils.bindattrFormat;
	import ui.utils.dialogProperty;
	import ui.utils.initUIContainer;
	import ui.utils.reqDialogService;
	import ui.utils.setPosUnit;
	import vndecl.*;
	
	/**
	 * ...
	 * @author anod
	 */
	public class SetTimesegDate extends basePannel implements IFrame
	{
		use namespace ns_vname_decl;
		use namespace ns_group_handler;
		
		private var mFrame:FSetExecTime;
		
		[Embed(source="../../../lib/include_day.png")]
		private var mDayCheck:Class;
		private var mDayChkbmp:BitmapData;
		
		/**
		 * 这个变量记录每个班次的日期状态。key - 班次ID value - Dictionary
		 * 这个value呢，表示某个日期的状态，这个日期的状态结构是今天排几个人（0今天公休 N排的人数）
		 * 所以value的格式为 key - 日期time value - 状态
		 */
		private var mWorkday4Timeseg:Dictionary;
		
		/**
		 * 这个变量记录每个班次中哪些日期当前被选中了。
		 * key - 班次ID value - Array(单个元素uiUnit)
		 */
		private var mSelectedEditday:Dictionary;
		
		private const milliseconds_per_day:int = 1000 * ( 24 * 60 * 60 );
		
		public function SetTimesegDate( frame:FSetExecTime )
		{
			mFrame = frame;
			addChild( mFrame );
			super();
			
			mWorkday4Timeseg = new Dictionary();
			
			var tmpbmp:Bitmap = new mDayCheck();
			mDayChkbmp = tmpbmp.bitmapData;
			
			setupInteractive();
			setupDataMonitor();
		}
		
		/* INTERFACE frame.IFrame */
		
		public function setupInteractive():void 
		{
			iNextButton.click       = "nextPanel";
			iPrevButton.click       = "prevPanel";
			iCancelButton.click     = "switchChild";
			iTimesegTable.handler   = "listTimeseg";
			iTimesegTable.hook      = "resetWorkday";
			iScrollBar.area         = "iTimesegTable";
		}
		
		public function setupDataMonitor():void 
		{
			iTimesegTable.data      = VNGM.PROXY_TIMESEG;
		}
		
		// UI回调
		//----------------------------------------------
		/** 显示一个“日历”单元 */
		ns_group_handler function listTimeseg( entry:uiUnit, timeseg:StructTime ):void
		{
			var content:UDateTimeseg = new UDateTimeseg();
			with ( content )
			{
				iNameText.component.text = "班次：" + timeseg.name;
				iMonthTable.component.data = VNIC.EXEC_MONTHDATA;
				iMonthTable.component.handler = "listWeek";
				iIncButton.visible = false;
				iDecButton.visible = false;
				iDelButton.visible = false;
				iIncButton.component.click   = "timesegEnlarge";
				iDecButton.component.click   = "timesegReduce";
				iDelButton.component.click   = "skipSelectedDay";
			}
			attrControl.bindAttr(content.iDescText.component, "text", bindattrFormat(VNIC.EXEC_WEEKDATA, "countWorkday") );
			initUIContainer( content );

			entry.addChild( content );
		}
		
		/** 显示一个“月份日历” */
		ns_group_handler function listWeek( entry:uiUnit, month_info:Point ):void
		{
			var list_handler:Function = dialogProperty( parent, "listWeek", typeof(this) );
			list_handler( entry, month_info );
		}
		
		/** 显示一个“哪一天” */
		ns_group_handler function listWeekday( entry:uiUnit, day_info:int ):void
		{
			reqDialogService( this, "listWeekday", [entry, day_info] );
			
			var bmpsel:Bitmap = new Bitmap();
			entry.addChild( bmpsel );
			
			entry.click = "onCheckDay";
			entry.dclick = "onCheckMonth";
			
			entry.mouseChildren = false;
			entry.tips = "";
			entry.tooltip.content = genDayTips( entry );
		}
		
		/** 重置mWorkday4Timeseg */
		ns_group_hook function resetWorkday( group:uiGroup ):void
		{
			mSelectedEditday = new Dictionary();
			mWorkday4Timeseg = new Dictionary();
			iScrollBar.visible = group.height > mFrame.iTimesegTable.scrollRect.height;
		}
		
		/** 选中某一天 */
		ns_interactive_slot function onCheckDay( entry:uiUnit ):void
		{
			var id:int = getStructTimeByUnit( entry ).ID;
			
			var dates:Array = mSelectedEditday[id];
			clearCheck( dates ) && enableOption( entry, false );
			
			if ( dates && dates.length == 1 && dates[0] == entry )//取消选中
			{
				delete mSelectedEditday[id];
				checkUnit( entry, false ) && enableOption( entry, true );
				enableOption( entry, false );
			}
			else //执行选中
			{
				mSelectedEditday[id] = [entry];
				checkUnit( entry, true ) && enableOption( entry, true );
			}
		}
		
		/** 选中某个月 */
		ns_interactive_slot function onCheckMonth( entry:uiUnit ):void
		{
			var id:int = getStructTimeByUnit( entry ).ID;
			var dates:Array = mSelectedEditday[id];
			clearCheck( dates ) && enableOption( entry, false );
			
			dates = [];
			var group:uiGroup = entry.parent as uiGroup;
			for ( var i:int = 0; i < group.numChildren; ++i )
			{
				var day:uiUnit = group.getChildAt(i) as uiUnit;
				dates.push( day );
				checkUnit( day, true );
			}
			enableOption( entry, true );
			mSelectedEditday[id] = dates;
		}
		/** 选中的单元，增加日子 */
		ns_interactive_slot function timesegEnlarge( button:ui_button ):void
		{
			var timeseg:StructTime = getStructTimeByButton( button );
			var id:int = timeseg.ID;
			
			var workday_at_id:Dictionary = mWorkday4Timeseg[id];
			if ( workday_at_id == null ) workday_at_id = new Dictionary();
			
			var dates:Array = mSelectedEditday[id];
			for each( var unit:uiUnit in dates )
			{
				var time:Number = getDateObjectByUnit(unit).time;
				var size:int = workday_at_id[time];
				if ( workday_at_id[time] == undefined ) size = timeseg.size;
				++size;
				workday_at_id[time] = size;
				applySize( unit, size, timeseg.size );
			}
			mWorkday4Timeseg[id] = workday_at_id;
			updateWorkdayCount( id );
		}
		/** 选中的单元，减少日子 */
		ns_interactive_slot function timesegReduce( button:ui_button ):void
		{
			var timeseg:StructTime = getStructTimeByButton( button );
			var id:int = timeseg.ID;
			
			var workday_at_id:Dictionary = mWorkday4Timeseg[id];
			if ( workday_at_id == null ) workday_at_id = new Dictionary();
			
			var dates:Array = mSelectedEditday[id];
			for each( var unit:uiUnit in dates )
			{
				var time:Number = getDateObjectByUnit(unit).time;
				var size:int = workday_at_id[time];
				if ( workday_at_id[time] == undefined ) size = timeseg.size;
				if ( size > 0 ) --size;
				workday_at_id[time] = size;
				applySize( unit, size, timeseg.size );
			}
			mWorkday4Timeseg[id] = workday_at_id;
			updateWorkdayCount( id );
		}
		/** 选中的单元，不排班 */
		ns_interactive_slot function skipSelectedDay( button:ui_button ):void
		{
			var timeseg:StructTime = getStructTimeByButton( button );
			var id:int = timeseg.ID;
			
			var workday_at_id:Dictionary = mWorkday4Timeseg[id];
			if ( workday_at_id == null ) workday_at_id = new Dictionary();
			
			var dates:Array = mSelectedEditday[id];
			for each( var unit:uiUnit in dates )
			{
				var time:Number = getDateObjectByUnit(unit).time;
				var size:int = workday_at_id[time];
				if ( workday_at_id[time] == undefined ) size = timeseg.size;
				size = 0;
				workday_at_id[time] = size;
				applySize( unit, size, timeseg.size );
			}
			mWorkday4Timeseg[id] = workday_at_id;
			updateWorkdayCount( id );
		}
		/** 得到各个时间段的工作日字符串 */
		ns_bindattr_filter function countWorkday( day_of_months:Array, txt:ui_text_block ):String
		{
			const format:String = "排班信息：共{0}天，其中工作日{1}天【每个值班人员总排班天数，可在后续面板调整】";
			
			var day_cnt:int = 0;
			var workday_cnt:int = 0;
			
			// 休息日表格[ key - 一个月对7取模天数 value - [key第一天是星期几:value这个星期有几个休息日] ]
			const weekend_correct_table:Object = 
			{
				"0": { },
				"1": { 0:1, 6:1 },
				"2": { 0:1, 5:1, 6:2 },
				"3": { 0:1, 4:1, 5:2, 6:2 },
				"4": { 0:1, 3:1, 4:2, 5:2, 6:2 },
				"5": { 0:1, 2:1, 3:2, 4:2, 5:2, 6:2 },
				"6": { 0:1, 1:1, 2:2, 3:2, 4:2, 5:2, 6:2 }
			};
			
			// 得到总日期
			for each( var days_of_month:Array in day_of_months )
			{
				var num_days_in_month:int = days_of_month.length;
				day_cnt += num_days_in_month;
				workday_cnt += num_days_in_month - ( 2*Math.floor(num_days_in_month/7) + int(weekend_correct_table[num_days_in_month%7][days_of_month.offset]) );
			}
			
			// 剔除设置好的日期
			var entry:uiUnit = txt.parent.parent.parent as uiUnit;
			var timeseg:StructTime = entry.data;
			var workdays_at_id:Dictionary = mWorkday4Timeseg[timeseg.ID];
			for ( var k:* in workdays_at_id )
			{
				var select_day_time:Number = Number(k);
				var size:int = workdays_at_id[select_day_time];
				if ( size == 0 )
				{
					--day_cnt;
					var select_day_date:Date = new Date();
					select_day_date.setTime( select_day_time );
					if ( (1+select_day_date.day)%7 > 1 )
						--workday_cnt;
				}
			}
			
			return StringUtil.substitute( format, day_cnt, workday_cnt );
		}
	
		//常用函数
		//------------------------------------
		private function getDateObjectByUnit( entry:uiUnit ):Date							//从一个日期的unit得到这个日期的date
		{
			var week_group:uiGroup = entry.parent as uiGroup;
			var month_unit:uiUnit = week_group.parent as uiUnit;
			
			var date:Number = month_unit.data.x;
			date += milliseconds_per_day * (entry.data-1);
			var retval:Date = new Date();
			retval.setTime( date );
			return retval;
		}
		private function getStructTimeByUnit( entry:uiUnit ):StructTime						//从一个日期的uiunit得到这个日期所在的timeseg
		{
			var week_group:uiGroup = entry.parent as uiGroup;
			var month_unit:uiUnit = week_group.parent as uiUnit;
			var month_group:uiGroup = month_unit.parent as uiGroup;
			var time_unit:uiUnit = month_group.parent.parent.parent as uiUnit;
			return time_unit.data;
		}
		private function enableOption( entry:uiUnit, enabled:Boolean ):void					//开启/关闭三个功能按钮
		{
			var week_group:uiGroup = entry.parent as uiGroup;
			var month_unit:uiUnit = week_group.parent as uiUnit;
			var month_group:uiGroup = month_unit.parent as uiGroup;
			var unit:UDateTimeseg = month_group.parent.parent as UDateTimeseg;
			unit.iIncButton.visible = unit.iDecButton.visible = unit.iDelButton.visible = enabled;
		}
		private function checkUnit( entry:uiUnit, check:Boolean ):Boolean					//某个日期unit被选中或者取消选中后的显示处理
		{
			var bmp:Bitmap = entry.getChildAt(1) as Bitmap;
			bmp.bitmapData = check ? mDayChkbmp : null;
			return check;
		}
		private function clearCheck( units:Array ):Boolean									//取消选中所有的unit
		{
			for each( var entry:uiUnit in units )
				checkUnit( entry, false );
			return true;
		}
		private function getStructTimeByButton( button:ui_button ):StructTime				//从功能按钮得到所在的timeseg
		{
			var time_unit:uiUnit = button.parent.parent.parent as uiUnit;
			return time_unit.data;
		}
		private function applySize( entry:uiUnit, curr_size:int, std_size:int ):void		//设置某个日期unit的值班人数的显示处理
		{
			var txt:ui_text = entry.getChildAt(0) as ui_text;
			var bmp:Bitmap = entry.getChildAt(1) as Bitmap;
			
			if ( curr_size == 0 ) 
			{
				txt.bold = false;
				txt.underline = false;
				txt.textfield.filters = [];
				txt.alpha = 0.1;
			}
			else if ( curr_size < std_size )
			{
				txt.bold = false;
				txt.underline = true;
				txt.textfield.filters = [];
				txt.alpha = 0.6;
			}
			else if ( curr_size > std_size ) 
			{
				txt.bold = true;
				txt.underline = false;
				txt.textfield.filters = [new GlowFilter(0x1127, 1, 10, 10)];
				txt.alpha = 1;
			}
			else 
			{
				txt.bold = true;
				txt.underline = false;
				txt.stroke = 0x4f4f4f;
				txt.alpha = 1;
			}
		}
		private function genDayTips( entry:uiUnit ):Function								//日期unit的鼠标tips
		{
			const format:String = "<p align='left'><textformat leading='4'>{0}/{1}/{2}<br/>值班：{3}人</textformat></p>";
			return function():String
			{
				var timeseg:StructTime = getStructTimeByUnit( entry );
				var id:int = timeseg.ID;
				var workday_at_id:Dictionary = mWorkday4Timeseg[id];
				var date:Date = getDateObjectByUnit( entry );
				if ( workday_at_id == null ) 
				{
					return StringUtil.substitute(format, date.fullYear, date.month + 1, date.date, timeseg.size);
				}
				else if ( workday_at_id[date.time] == undefined ) 
				{
					return StringUtil.substitute(format, date.fullYear, date.month + 1, date.date, timeseg.size);
				}
				else
				{
					return StringUtil.substitute(format, date.fullYear, date.month + 1, date.date, workday_at_id[date.time]);
				}
			}
		}
		private function updateWorkdayCount( id:int ):void									//班次unit的desc文字，手动更新
		{
			var all_timeseg:Vector.<StructTime> = DataMonitor.getData( iTimesegTable.data );
			var key_of_unit:int = -1;
			for ( var i:int = 0; i < all_timeseg.length; ++i )
			{
				if ( all_timeseg[i].ID == id )
				{
					key_of_unit = i;
					break;
				}
			}
			ASSERT( key_of_unit >= 0 );
			
			var timeseg_entry:uiUnit = iTimesegTable.getUnitByKey( key_of_unit );
			var content:UDateTimeseg = timeseg_entry.getChildAt(0) as UDateTimeseg;
			var txt:ui_text_block = content.iDescText.component;
			txt.text = ns_bindattr_filter::countWorkday( DataMonitor.getData( VNIC.EXEC_WEEKDATA ), txt );
		}
		
		//交互组件定义
		//------------------------------------
		public function get iNextButton():ui_button
		{
			return mFrame.iNextButton.component;
		}
		public function get iPrevButton():ui_button
		{
			return mFrame.iPrevButton.component;
		}
		public function get iCancelButton():ui_button
		{
			return mFrame.iCancelButton.component;
		}
		public function get iScrollBar():ui_scroll_bar
		{
			return mFrame.iScrollBar.component;
		}
		public function get iTimesegTable():uiGroup
		{
			return mFrame.iTimesegTable.component;
		}
	}

}